﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="../css/common.css" media="all" />
<link rel="stylesheet" type="text/css" href="../css/article.css" media="all" />
</head>
<body>
<div id="w3h_body">
  <div class="body_content">
    <!-- toc begin -->
    <h1 class="title">SD9025: IE6 IE7 IE8 Opera 支持除 INPUT 和 BUTTON 元素以外的其他元素的 'click' 方法</h1>
    <ul class="toc">
      <li><a href="#standard_reference">标准参考</a> <span>•</span></li>
      <li><a href="#description">问题描述</a> <span>•</span></li>
      <li><a href="#influence">造成的影响</a> <span>•</span></li>
      <li><a href="#impacted_browsers">受影响的浏览器</a> <span>•</span></li>
      <li><a href="#analysis_of_issues">问题分析</a> <span>•</span></li>
      <li><a href="#solutions">解决方案</a> <span>•</span></li>
      <li><a href="#see_also">参见</a></li>
    </ul>
    <!-- toc end -->
    <div id="w3h_content">
      <!-- content begin -->
      <address class="author">作者：孙东国</address>
      <h2 id="standard_reference">标准参考</h2>
      <p> &quot;click&quot; 方法用于模拟一个鼠标点击事件，可应用于 &quot;type&quot; 属性值为 &quot;button&quot; &quot;checkbox&quot; &quot;radio&quot; &quot;reset&quot; &quot;submit&quot; 的 INPUT 元素上，其他元素的 &quot;click&quot; 方法规范中并没有提及。 </p>
      <p> 关于 &quot;click&quot; 方法请参考 W3C DOM-Level-2 中 <a href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-2651361">Interface HTMLInputElement</a> 的描述。 </p>
      <h2 id="description">问题描述</h2>
      <p><em>IE6 IE7 IE8 Opera</em> 支持除 INPUT 和 BUTTON 元素以外的其他元素的 &quot;click&quot; 方法，这使得各浏览器对除 INPUT 和 BUTTON 元素以外的其他元素的 &quot;click&quot; 的支持情况存在差异。</p>
      <h2 id="influence">造成的影响</h2>
      <p>由于各浏览器对除 INPUT 和 BUTTON 元素以外的其他元素的 &quot;click&quot; 方法的支持情况存在差异，将导致除 INPUT 和 BUTTON 元素以外的其他元素的 &quot;click&quot; 方法模拟的鼠标点击所触发的函数在某些浏览器中不能得到响应。</p>
      <h2 id="impacted_browsers">受影响的浏览器</h2>
      <table class="list">
        <tr>
          <th>所有浏览器</th>
          <td></td>
        </tr>
      </table>
      <h2 id="analysis_of_issues">问题分析</h2>
      <p>在现行 HTML 4.01 规范中 “click” 方法仅可应用于 &quot;type&quot; 属性值为 &quot;button&quot; &quot;checkbox&quot; &quot;radio&quot; &quot;reset&quot; &quot;submit&quot; 的 INPUT 元素上。</p>
      <p>但，HTML 5 草案中 HTMLElement 接口说明中存在 &quot;click&quot; 方法，这表示着在未来 HTML 发展趋势中，所有 HTML 元素均有可能拥有 &quot;click&quot; 方法。</p>
      <p>详情可以参考 <a href="http://www.w3.org/TR/html5/elements.html#htmlelement">HTML 5 3.2.2 Elements in the DOM </a> 中 HTMLElement 接口说明文档。</p>
      <p>同时，在 IE 的厂商制定规范中也存在对  &quot;click&quot; 方法的描述，所有的 Element Constructor 均支持这个方法。</p>
      <p>详情可以参考 <a href="http://msdn.microsoft.com/en-us/library/ms536363(VS.85).aspx">MSND click Method</a> 中相关描述。</p>
      <p>由上可见，现行规范、规范草案、以及厂商标准均有差异。在新版本浏览器纷纷支持 HTML 5 草案规范的情况下，我们构建如下测试用例检测所有 HTML 元素对 &quot;click&quot; 方法的支持性。</p>
      <pre>
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script&gt;
    var tags = ['A','AREA','ABBR','ACRONYM','ADDRESS','B','BDO','BIG','BLOCKQUOTE','BR','BUTTON','CAPTION','CENTER','CITE','CODE',
                'COL','COLGROUP','DD','DEL','DIR','DIV','DFN','DL','DT','EM','FIELDSET','FONT','FORM','H1','H2','H3','H4','H5','H6',
                'HR','I','IMG','INPUT','INS','IFRAME','KBD','LABEL','LEGEND','LI','MAP','MENU','OBJECT','OL','EMBED','P','PRE','Q',
                'S','SAMP','SELECT','SMALL','SPAN','STRIKE','STRONG','SUB','SUP','TABLE','TBODY','TD','TEXTAREA','TFOOT','TH','THEAD',
                'TR','TT','U','UL','VAR'];
    var htmls = [
                '&lt;a href =&quot;javascript:void 0;&quot;&gt;A&lt;/a&gt;',
                '&lt;img src=&quot;google.gif&quot; usemap=&quot;#planetmap&quot; /&gt;&lt;map name=&quot;planetmap&quot;&gt;          \
                 &lt;area  shape=&quot;rect&quot; coords=&quot;0,0,50,50&quot; href =&quot;javascript:void 0;&quot;/&gt;&lt;/map&gt;',
                '&lt;abbr&gt;ABBR&lt;/abbr&gt;',
                '&lt;acronym&gt;ACRONYM&lt;/acronym&gt;',
                '&lt;address&gt;ADDRESS&lt;/address&gt;',
                '&lt;b&gt;B&lt;/b&gt;',
                '&lt;bdo&gt;BDO&lt;/bdo&gt;',
                '&lt;big&gt;BIG&lt;/big&gt;',
                '&lt;blockquote&gt;BLOCKQUOTE&lt;/blockquote&gt;',
                '&lt;br/&gt;',
                '&lt;button type=&quot;button&quot;&gt;BUTTON(button)&lt;/button&gt;',
                '&lt;button type=&quot;reset&quot;&gt;BUTTON(reset)&lt;/button&gt;',
                '&lt;button type=&quot;submit&quot;&gt;BUTTON(submit)&lt;/button&gt;',
                '&lt;table&gt;&lt;caption&gt;CAPTION&lt;/caption&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;',
                '&lt;center&gt;CENTER&lt;/center&gt;',
                '&lt;cite&gt;CITE&lt;/cite&gt;',
                '&lt;code&gt;CODE&lt;/code&gt;',
                '&lt;table&gt;&lt;col/&gt;&lt;tr&gt;&lt;td&gt;COL&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;',
                '&lt;table&gt;&lt;colgroup &gt;&lt;/colgroup&gt;&lt;tr&gt;&lt;td&gt;COLGROUP&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;',
                '&lt;dd&gt;DD&lt;/dd&gt;',
                '&lt;del&gt;DEL&lt;/del&gt;',
                '&lt;dir&gt;DIR&lt;/dir&gt;',
                '&lt;div&gt;DIV&lt;/div&gt;',
                '&lt;dfn&gt;DFN&lt;/dfn&gt;',
                '&lt;dl&gt;DL&lt;/dl&gt;',
                '&lt;dt&gt;DT&lt;/dt&gt;',
                '&lt;em&gt;EM&lt;/em&gt;',
                '&lt;fieldset&gt;FIELDSET&lt;/fieldset&gt;',
                '&lt;font&gt;FONT&lt;/font&gt;',
                '&lt;form&gt;FORM&lt;/form&gt;',
                '&lt;h1&gt;H1&lt;/h1&gt;',
                '&lt;h2&gt;H2&lt;/h2&gt;',
                '&lt;h3&gt;H3&lt;/h3&gt;',
                '&lt;h4&gt;H4&lt;/h4&gt;',
                '&lt;h5&gt;H5&lt;/h5&gt;',
                '&lt;h6&gt;H6&lt;/h6&gt;',
                '&lt;hr/&gt;',
                '&lt;i&gt;I&lt;/i&gt;',
                '&lt;input type=&quot;text&quot;/&gt;',
                '&lt;input type=&quot;checkbox&quot;/&gt;',
                '&lt;input type=&quot;hidden&quot;/&gt;',
                '&lt;input type=&quot;image&quot;/&gt;',
                '&lt;input type=&quot;password&quot;/&gt;',
                '&lt;input type=&quot;radio&quot;/&gt;',
                '&lt;input type=&quot;reset&quot;/&gt;',
                '&lt;input type=&quot;submit&quot;/&gt;',
                '&lt;input type=&quot;file&quot;/&gt;',
                '&lt;ins&gt;INS&lt;/ins&gt;',
                '&lt;iframe  src=&quot;google.html&quot;&gt;&lt;/iframe&gt;',
                '&lt;kbd&gt;KBD&lt;/kbd&gt;',
                '&lt;label&gt;LABEL&lt;/label&gt;',
                '&lt;fieldset&gt;&lt;legend &gt;LEGEND&lt;/legend&gt;fieldset&lt;/fieldset&gt;',
                '&lt;li&gt;LI&lt;/li&gt;',
                '&lt;menu&gt;MENU&lt;/menu&gt;',
                '&lt;object  type=&quot;application/x-shockwave-flash&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;google.gif&quot; /&gt;&lt;/object&gt;',
                '&lt;ol&gt;OL&lt;/ol&gt;',
                '&lt;embed  type=&quot;application/x-shockwave-flash&quot; src=&quot;clock.swf&quot; /&gt;',
                '&lt;p&gt;P&lt;/p&gt;',
                '&lt;pre&gt;PRE&lt;/pre&gt;',
                '&lt;q&gt;Q&lt;/q&gt;',
                '&lt;s&gt;S&lt;/s&gt;',
                '&lt;samp&gt;SAMP&lt;/samp&gt;',
                '&lt;select&gt;&lt;option&gt;SELECT&lt;/option&gt;&lt;/select&gt;',
                '&lt;small&gt;SMALL&lt;/small&gt;',
                '&lt;span&gt;SPAN&lt;/span&gt;',
                '&lt;strike&gt;STRIKE&lt;/strike&gt;',
                '&lt;strong&gt;STRONG&lt;/strong&gt;',
                '&lt;sub&gt;SUB&lt;/sub&gt;',
                '&lt;sup&gt;SUP&lt;/sup&gt;',
                '&lt;textarea &gt;TEXTAREA&lt;/textarea&gt;',
                '&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;TABLE&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;',
                '&lt;table&gt;&lt;tfoot&gt;&lt;tr&gt;&lt;td&gt;TFOOT&lt;/td&gt;&lt;/tr&gt;&lt;/tfoot&gt;&lt;/table&gt;',
                '&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th &gt;TH&lt;/th&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;',
                '&lt;table&gt;&lt;thead &gt;&lt;tr&gt;&lt;td&gt;THEAD&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;/table&gt;',
                '&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;TR&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;',
                '&lt;tt&gt;TT&lt;/tt&gt;',
                '&lt;u&gt;U&lt;/u&gt;',
                '&lt;ul&gt;UL&lt;/ul&gt;',
                '&lt;var&gt;VAR&lt;/var&gt;'
        ];
    windowfunction element_click(){
        document.getElementById(&quot;container&quot;).style.display=&quot;block&quot;;
        document.getElementById(&quot;info1&quot;).style.display=&quot;block&quot;;
        document.getElementById(&quot;info2&quot;).style.display=&quot;block&quot;;
        for(var i in htmls){
            document.getElementById(&quot;container&quot;).innerHTML+=htmls[i];
            document.getElementById(&quot;container&quot;).innerHTML+=&quot;&lt;br/&gt;&quot;;
            document.getElementById(&quot;inited&quot;).onclick=&quot;&quot;;
        }
        var flag;
        for(var i in tags){
      flag=0;
            if(document.getElementsByTagName(tags[i])){
                var elements=document.getElementsByTagName(tags[i]);
                if(tags[i]==&quot;BUTTON&quot;||tags[i]==&quot;INPUT&quot;){
                 for(var j=0;j&lt;elements.length;j++){
                     flag=0;
                     try{
                            elements[j].click();
                        }catch(e){
                           document.getElementById(&quot;info1&quot;).innerHTML+=i+&quot;.&quot;+tags[i]+&quot;[type=&quot;+elements[j].type+&quot;] :&quot;+e+&quot;&lt;br/&gt;&quot;;
                           flag=1;
                        }
                     if(flag==0)
                        document.getElementById(&quot;info2&quot;).innerHTML+=i+&quot;.&quot;+tags[i]+&quot;[type=&quot;+elements[j].type+&quot;] :&quot;+&quot;支持Click()&lt;br/&gt;&quot;;
                    }
                }
                else{
                    try{
                        elements[0].click();
                    }
                    catch(e){
                        document.getElementById(&quot;info1&quot;).innerHTML+=i+&quot;.&quot;+tags[i]+&quot; :&quot;+e+&quot;&lt;br/&gt;&quot;;
                        flag=1;
                        }
                    if(flag==0)
                        document.getElementById(&quot;info2&quot;).innerHTML+=i+&quot;.&quot;+tags[i]+&quot; :&quot;+&quot;支持Click()&lt;br/&gt;&quot;;
                    }
                }
            }
  }
&lt;/script&gt;
&lt;input  type=&quot;button&quot; value=&quot;点击此按键开始测试所有 HTML 标签的 Click 方法支持程度&quot; id=&quot;inited&quot; onclick=&quot;element_click()&quot;/&gt;
&lt;div id=&quot;container&quot; style=&quot;border:1px solid black;display:none;&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;info1&quot; style=&quot;border:1px solid red;display:none;&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;info2&quot; style=&quot;border:1px solid blue;display:none;&quot;&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
      <p>以上代码中数组 &quot;htmls&quot; 为向页面输出需要测试的所有 HTML 元素，数组 &quot;tags&quot; 用于之后获得这些 HTML 元素时 &quot;getElementsByTagName&quot; 的函数参数，&quot;element_click&quot; 方法的主要思想是首先将数组 &quot;htmls&quot; 中的元素以 HTML 元素的形式输出到页面，然后通过 &quot;getElementsByTagName&quot; 方法并将数组 &quot;tags&quot; 中的元素做为其形参获得每一个上一步骤中输出到页面中的元素，最后通过 <em>try{...}catch(Exception e){...}</em> 检测每一个 HTML 元素在执行 &quot;click&quot; 方法时是否发生异常，如发生异常则捕获并将其输出，否则表示该元素支持 &quot;click&quot; 方法。</p>
      <p>测试结果归纳如下：</p>
      <table class="compare">
        <tr>
          <th>&nbsp;</th>
          <th>IE6 IE7 IE8 Opera</th>
          <th>Firefox Safari Chrome</th>
        </tr>
        <tr>
          <th  style="text-align:left;"> INPUT[type=text]<br />
            INPUT[type=password]<br />
            INPUT[type=radio]<br />
            INPUT[type=checkbox]<br />
            INPUT[type=button]<br />
            INPUT[type=submit]<br />
            INPUT[type=image]<br />
            INPUT[type=hidden]<br />
            INPUT[type=reset]<br />
            INPUT[type=submit]<br />
            INPUT[type=file]<sup>1</sup><br />
            BUTTON[type=button] </th>
          <td><span class="hl_2">支持</span></td>
          <td><span class="hl_2">支持</span></td>
        </tr>
        <tr>
          <th  style="text-align:left;"> 其他 HTML 元素 </th>
          <td><span class="hl_2">支持</span></td>
          <td><span class="hl_1">不支持</span></td>
        </tr>
      </table>
      <p>从上例运行结果的归纳总结可见：</p>
      <ul>
        <li><em>IE6 IE7 IE8 Opera</em> 中，所有 HTML 元素均支持直接使用  &quot;click&quot; 方法触发单击事件。</li>
        <li><em>Firefox Safari Chrome</em> 中，仅支持对 INPUT BUTTON 元素，直接使用  &quot;click&quot; 方法触发其单击事件。</li>
      </ul>
      <p><span class="comment">【注】：IE6 IE7 IE8 Safari Chrome 中，调用 input[type=file] 元素的 &quot;click&quot; 方法会使浏览器弹出选择文件对话框，而 Firefox 和 Opera 则没有将选择文件对话框打开，这可能是出于某种安全因素考虑。</span></p>
      <p>综上所述，BUTTON 元素的 &quot;click&quot; 方法已经被所有浏览器支持，超出了现行 HTML 4.01 规范，正在贴近 HTML 5 草案。另外，Opera 更好的支持了 HTML 5 草案，而 IE6 IE7 IE8 完全遵循了自身的厂商扩展定义。</p>
      <h2 id="solutions">解决方案</h2>
      <p>建议尽量避免对除 INPUT 和 BUTTON 元素以外的其他元素通过 &quot;click&quot; 方法模拟鼠标点击事件。</p>
      <p>如需对其元素使用  &quot;click&quot; 方法触发 &quot;onClick&quot; 事件处理程序，可以通过以下两种方式解决：</p>
      <ul>
        <li>由于大多数情况下调用 &quot;click&quot; 方法所实现的无非是执行某一元素所绑定的事件处理函数，因此可以直接调用该元素所对应的 &quot;click&quot; 事件处理函数。</li>
        <li>或者使用 DOM-Level-2-Events 标准内 <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-document">DocumentEvent interface</a> 、<a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface">Event interface</a> 和 <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Registration-interfaces">Event registration interfaces</a> 相关定义中的 &quot;createEvent&quot; &quot; initEvent&quot; 以及 &quot;dispatchEvent&quot;方法建立 &quot;click&quot; 事件并派发出去。如：
<pre>
function createEvent (eventTarget,eventName){
    try{
        if(eventTarget.dispatchEvent){
            var evt = document.createEvent("MouseEvents");
            evt.initEvent(eventName,false,true);
            eventTarget.dispatchEvent(evt);
        }else if(eventTarget.fireEvent){
            eventTarget.fireEvent('on'+eventName);
        }else{
            eventTarget[ type ]();
        }
    }catch(e){
        alert(e);
    }
}
createEvent(HTMLElement,'click');
</pre>
        </li>
      </ul>
      <h2 id="see_also">参见</h2>
      <h3>知识库</h3>
      <ul class="see_also">
        <li><a href="#">...</a></li>
      </ul>
      <h3>相关问题</h3>
      <ul class="see_also">
        <li><a href="#">...</a></li>
      </ul>
      <div class="appendix">
        <h2>测试环境</h2>
        <table class="list">
          <tr>
            <th>操作系统版本:</th>
            <td>Windows 7 Ultimate build 7600</td>
          </tr>
          <tr>
            <th>浏览器版本:</th>
            <td> IE6<br />
              IE7<br />
              IE8<br />
              Firefox 3.6.11<br />
              8.0.552.11 dev<br />
              Safari 5.0.2 <br />
              Opera 10.63 </td>
          </tr>
          <tr>
            <th>测试页面:</th>
            <td><a href="../../tests/SD9025/click.html">click.html</a></td>
          </tr>
          <tr>
            <th>本文更新时间:</th>
            <td>2010-10-18</td>
          </tr>
        </table>
        <h2>关键字</h2>  
        <!-- keywords begin -->
        <p>click onclick</p>
        <!-- keywords end -->
      </div>
      <!-- content end -->
    </div>
  </div>
</div>
</body>
</html>
